package com.ruslan.magaz.repository;

import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.ruslan.magaz.domain.Address;
import com.ruslan.magaz.domain.Customer;
import com.ruslan.magaz.domain.Order;
import com.ruslan.magaz.domain.Role;
import com.ruslan.magaz.domain.User;


@Repository
public class UserDaoImpl implements UserDao{

	@Autowired
	private SessionFactory sessionFactory;
	
	@Override
	public void addUser(User user) {
		sessionFactory.getCurrentSession().save(user);
	}

	@Override
	public void removeUser(User user) {
		sessionFactory.getCurrentSession().delete(user);
	}

	@Override
	public User getUserById(Integer id) {
		return (User) sessionFactory.getCurrentSession().get(User.class, id);
	}

	@Override
	public List<User> getAllUsers() {
		  Query query = sessionFactory.getCurrentSession().createQuery("FROM User");
		  return  (List<User>) query.list();
	}
	
	@Override
	public User login(String login, String password) {
		  Query query = sessionFactory.getCurrentSession().createQuery("SELECT u FROM User u WHERE Name = :login AND Password = :password");
		  query.setString("login", login);
		  query.setString("password", password);
		  return  (User) query.uniqueResult();
	}

	@Override
	public void editUser(User user) {
		  Session session = sessionFactory.getCurrentSession();
		  User existingUser = (User) session.get(User.class, user.getUserId());
		  // Assign updated values to this person
		  existingUser.setName(user.getName());
		  existingUser.setEmail(user.getEmail());
		  existingUser.setPassword(user.getPassword());		 
		  // Save updates
//		  session.update(existingUser);
	}
	
	@Override
	public Integer getFirstUserId() {
		Session session = sessionFactory.getCurrentSession();
		Query query = session.createQuery("SELECT min(u.userId) FROM User u");
		query.setFirstResult(0);
		return  (Integer) query.uniqueResult();
	}

	@Override
	public List<User> getAllUsersNotAdmin() {
		Session session = sessionFactory.getCurrentSession();
		Query query = session.createQuery("FROM User u where u.role.roleId != 2");
		return  (List<User>) query.list();
	}

	@Override
	public void addCustomer(int userId, Customer customer) {
		   
		  Session session = sessionFactory.getCurrentSession();
		  session.save(customer);
		  User existingUser = (User) session.get(User.class, userId);
		  existingUser.setCustomer(customer);		  
		 
		  // Save updates
//		  session.save(existingCustomer);
	}

	@Override
	public void removeCustomer(Customer customer) {
		sessionFactory.getCurrentSession().delete(customer);
		
	}

	@Override
	public Customer getCustomerById(Integer id) {
		return (Customer) sessionFactory.getCurrentSession().get(Customer.class, id);
	}

	@Override
	public List<Customer> getAllCustomers() {
		Query query = sessionFactory.getCurrentSession().createQuery("FROM Customer");
		return  (List<Customer>) query.list();
	}

	@Override
	public void editCustomer(Customer customer) {
		Session session = sessionFactory.getCurrentSession();
		Customer existingCustomer = (Customer) session.get(Customer.class, customer.getCustomerId());
		// Assign updated values to this person
		existingCustomer.setBirthDate(customer.getBirthDate());
		existingCustomer.setFirstName(customer.getFirstName());
		existingCustomer.setLastName(customer.getLastName());
		existingCustomer.setGender(customer.getGender());
		existingCustomer.setShippingAddressId(customer.getShippingAddressId());
		// Save updates
//		session.update(existingUser);
		
	}

	@Override
	public void addRole(Role role) {
		sessionFactory.getCurrentSession().save(role);
	}

	@Override
	public void removeRole(Role role) {
		sessionFactory.getCurrentSession().delete(role);
		
	}

	@Override
	public Role getRoleById(Integer id) {
		return (Role) sessionFactory.getCurrentSession().get(Role.class, id);
	}

	@Override
	public List<Role> getAllRoles() {
		Query query = sessionFactory.getCurrentSession().createQuery("FROM User");
		return  (List<Role>) query.list();
	}

	@Override
	public void editRole(Role role) {
		Session session = sessionFactory.getCurrentSession();
		Role existingCustomer = (Role) session.get(Role.class, role.getRoleId());
		// Assign updated values to this person
		existingCustomer.setRoleName(role.getRoleName());
		// Save updates
//		session.update(existingUser);
	}

	@Override
	public void addAddress(int userId, Address address) {
		Session session = sessionFactory.getCurrentSession();
		session.save(address);
		User existingUser = (User) session.get(User.class, userId);
		Customer existingCustomer = existingUser.getCustomer();
		existingCustomer.getAddresses().add(address);
		// Save updates
//		session.save(existingUser);
		
	}

	@Override
	public void removeAddress(Address address) {
		sessionFactory.getCurrentSession().delete(address);
		
	}

	@Override
	public Address getAddressById(Integer id) {
		return (Address) sessionFactory.getCurrentSession().get(Address.class, id);
	}

	@Override
	public List<Address> getAllAddresses() {
		Query query = sessionFactory.getCurrentSession().createQuery("FROM Address");
		return  (List<Address>) query.list();
	}
	@Override
	public List<Address> getAllAddressesForUser(int userId) {
		Session session = sessionFactory.getCurrentSession();
		User user = (User) session.get(User.class, userId);
		int customerId = user.getCustomer().getCustomerId();
		Query query = session.createQuery("SELECT a FROM Address a where customer_id = :id");
		query.setInteger("id", customerId);
		return  (List<Address>) query.list();
	}
	
	
	@Override
	public void editAddress(Address address) {
		Session session = sessionFactory.getCurrentSession();
		Address existingAddress = (Address) session.get(Address.class, address.getAddressId());
		// Assign updated values to this person
		existingAddress.setAddress1(address.getAddress1());
		existingAddress.setAddress2(address.getAddress2());
		existingAddress.setCity(address.getCity());
		existingAddress.setCountry(address.getCountry());
		existingAddress.setState(address.getState());
		existingAddress.setPhone(address.getPhone());
		existingAddress.setZip(address.getZip());
		// Save updates
//		session.update(existingUser);
	}

	@Override
	public void favAddress(int customerId, Address address) {
		Session session = sessionFactory.getCurrentSession();
		Customer existingCustomer = (Customer) session.get(Customer.class, customerId);
		existingCustomer.setShippingAddressId(address.getAddressId());
		
	}

	@Override
	public List<User> getUserByName(String name) {
		Query query = sessionFactory.getCurrentSession().createQuery("FROM User where name = :name");
		query.setString("name", name);
		return  (List<User>) query.list();
	}

	@Override
	public List<User> getUserByEmail(String email) {
		Query query = sessionFactory.getCurrentSession().createQuery("FROM User where email = :email");
		query.setString("email", email);
		return  (List<User>) query.list();
	}

	

}
